package com.yuan.yblog.portal.service;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuan.yblog.common.consts.Constants;
import com.yuan.yblog.common.consts.RedisKey;
import com.yuan.yblog.common.exception.Asserts;
import com.yuan.yblog.common.service.CaptchaService;
import com.yuan.yblog.crud.entity.OssFile;
import com.yuan.yblog.crud.entity.User;
import com.yuan.yblog.common.service.EntityCacheService;
import com.yuan.yblog.crud.service.IOssFileService;
import com.yuan.yblog.crud.service.IUserService;
import com.yuan.yblog.portal.pojo.VO.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import com.yuan.yblog.security.component.CustomPasswordEncoder;
import com.yuan.yblog.security.pojo.LoginUser;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashSet;

/**
 * @author 13527
 */
@Slf4j
@Service
public class UserService {
    @Autowired
    private IUserService iUserService;

    @Autowired
    private CaptchaService captchaService;

    @Autowired
    private CustomPasswordEncoder customPasswordEncoder;

    @Autowired
    private EntityCacheService entityCacheService;

    @Autowired
    AuthenticationService authenticationService;

    @Autowired
    OssService ossService;

    @Autowired
    IOssFileService iOssFileService;

    @Autowired
    AuthorityService authorityService;

    /**
     * 用户注册
     * @param username 用户名
     * @param password 密码（明文）
     * @param email 邮箱
     * @param captchaId 验证码标识
     * @param captcha 验证码
     */
    public Boolean register(String username, String password, String email, String captchaId, String captcha) {
        if(!captchaService.verifyCaptcha(captchaId,captcha)) {
            Asserts.fail("验证码错误");
        }
        //查询用户是否已存在
        long count = iUserService.count(new QueryWrapper<User>().eq("email",email));
        if(count > 0) {
            Asserts.fail("用户已存在");
        }

        //创建用户
        User user = new UserVO().toUserInsertEntity();
        user.setUsername(username);
        user.setEmail(email);
        //加密
        user.setPassword(customPasswordEncoder.encode(password));

        //插入数据库
        return iUserService.insert(user);
    }


    /**
     * 用户修改密码
     * @param oldPassword 旧密码（明文）
     * @param newPassword 新密码（明文）
     * @param ciphertext 数据库密码密文
     * @return true表示改密成功
     */
    public Boolean updatePassword(String oldPassword, String newPassword, String ciphertext) {
        User currentUser = authenticationService.getLoginUser();
        boolean isMe = false;
        if(customPasswordEncoder.matches(oldPassword, currentUser.getPassword())){
            isMe = true;
        }
        if(StrUtil.equals(ciphertext,currentUser.getPassword())){
            // 数据库密文校验通过，也给过
            isMe = true;
        }
        if(isMe){
            // 更新密码
            currentUser.setPassword(customPasswordEncoder.encode(newPassword));
            iUserService.updateAndDeleteCache(currentUser);
            //下线
            entityCacheService.deleteEntity(RedisKey.AUTH_LOGIN_USER,currentUser.getEmail());
            return true;
        }
        return false;
    }

    /**
     * 更新用户资料
     * @return 生效数目
     */
    public Boolean updateUserInfo(UserVO userVO) {
        User currentUser = authenticationService.getLoginUser();
        if(userVO.getId() == null || !currentUser.getId().equals(userVO.getId())){
            Asserts.fail("非法操作：用户id不匹配");
        }
        //更新
        boolean success = iUserService.updateAndDeleteCache(userVO.toUserInfoUpdateEntity());
        if (success) {
            // 重建登录信息
            authenticationService.buildLoginUser(authenticationService.getLoginUserDetails());
            return true;
        }
        return false;
    }

    /**
     * 获取基本用户信息
     * @param id 用户id
     */
    public UserVO getUserBasicInfo(Long id) {
        User user = iUserService.selectByIdAndBuildCache(id);
        HashSet<SimpleGrantedAuthority> authorities = authorityService.getUserAuthorities(id);
        return UserVO.getBasicInfoVO(user, authorities);
    }

    /**
     * 登录的用户获取自己的信息
     */
    public UserVO getLoginUserInfo() {
        // 从上下文获取用户信息
        LoginUser loginUser = authenticationService.getLoginUserDetails();
        HashSet<SimpleGrantedAuthority> authorities = authorityService.getUserAuthorities(loginUser.getUser().getId());
        // 抹去敏感信息
        UserVO user = UserVO.getDetailedInfoVO(loginUser.getUser(), authorities);
        // 配置权限信息
        user.setAuthorities(loginUser.getAuthorities());
        return user;
    }

    public boolean uploadAvatar(MultipartFile file){
        InputStream ins = null;
        String FileType = null;
        // 判断文件类型
        try {
            ins = file.getInputStream();
            FileType = FileTypeUtil.getType(ins);
            ins.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (!Constants.IMAGE_SUFFIX.contains(FileType)) {
            Asserts.fail("错误-不支持的图片类型：" + FileType);
        }
        // 判断文件大小
        if (file.getSize() >= Constants.USER_AVATAR_MAX_SIZE) {
            Asserts.fail("错误-图片不能超过" +Constants.USER_AVATAR_MAX_SIZE/1024/1024/8 + "MB，当前大小为" + file.getSize()/1024/1024/8 + "MB");
        }
        User loginUser = authenticationService.getLoginUser();
        // 上传
        String filePath = "user/avatar/" + loginUser.getId() + ".jpg";
        String ossUrl = ossService.upload(file, filePath, null);

        // 记录在文件表
        OssFile ossFile = new OssFile();
        ossFile.setPath(ossUrl);
        ossFile.setModule("user.avatar");
        ossFile.setModuleDataId(loginUser.getId());
        ossFile.setCreatedTime(new Date());
        ossFile.setScanTime(new Date());
        iOssFileService.save(ossFile);

        // 更新用户信息
        User user = iUserService.selectByIdAndBuildCache(loginUser.getId());
        user.setAvatar(ossUrl);
        iUserService.updateById(user);
        entityCacheService.deleteEntity(IUserService.USER, user.getId());

        return true;
    }
}




